package com.ship.contract.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ship.common.core.enums.MessageTypeEnum;
import com.ship.common.core.enums.ModuleUrlEnum;
import com.ship.common.core.exception.BusException;
import com.ship.common.core.utils.DateUtil;
import com.ship.common.core.utils.DateUtils;
import com.ship.common.core.utils.StringUtils;
import com.ship.common.core.web.domain.BaseResultCode;
import com.ship.common.security.utils.SecurityUtils;
import com.ship.contract.bean.*;
import com.ship.contract.mapper.ConThirdPartyMeasurementMapper;
import com.ship.contract.service.*;
import com.ship.contract.utils.FileUtil;
import com.ship.contract.mapper.ConstantMapper;
import com.ship.contract.utils.ObjectUtils;
import com.ship.system.api.BpmInstanceService;
import com.ship.system.api.RemoteMessageSendService;
import com.ship.system.api.domain.SysMessageSend;
import com.ship.system.api.model.ProcessInstanceParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service("ConThirdPartyMeasurementService")
public class ConThirdPartyMeasurementServiceImpl extends ContractBaseServiceImpl<ConThirdPartyMeasurementMapper, ConThirdPartyMeasurement> implements ConThirdPartyMeasurementService {

    @Autowired
    private ConOperateService conOperateService;

    @Autowired
    private ConAllLabelService conAllLabelService;

    @Autowired
    private ConFilesService conFilesService;

    @Autowired
    private ConExcellentCasesService conExcellentCasesService;

    @Autowired
    private ConstantMapper constantMapper;

    @Autowired
    private ConThirdPartyMeasurementMapper conThirdPartyMeasurementMapper;

    @Resource
    private RemoteMessageSendService remoteMessageSendService;

    @Value("${file.http-domain}")
    private String httpUrl;
    @Value("${file.https-domain}")
    private String httpsUrl;

    @Override
    public void delApply(Long id) {
        ConThirdPartyMeasurement conThirdPartyMeasurement = super.getById(id);
        if(conThirdPartyMeasurement == null){
            throw new BusException("删除申请失败!,该合同不存在", BaseResultCode.GENERAL_ERROR);
        }
        if(conThirdPartyMeasurement.getDelApply()==1){
            throw new BusException("当前合同已发起删除申请，请勿重复提交", BaseResultCode.GENERAL_ERROR);
        }
        conThirdPartyMeasurement.setDelApply(1);
        //启动删除审批流程
        ProcessInstanceParam param = new ProcessInstanceParam();
        param.setBussinessId(id);
        param.setBpmKey(BpmInstanceService.SYSTEM_DELETE_BPM_KEY);
        Map<String,Object> map = new HashMap<>();
        map.put("serviceType",4);
        map.put("module","con");
        map.put("moduleName","第三方计量合同");
        map.put("reason","");
        param.setParams(map);
        String processInstanceId = bpmInstanceService.startProcessInstance(param);
        conThirdPartyMeasurement.setDeleteProcessInstanceId(processInstanceId);
        super.updateById(conThirdPartyMeasurement);
    }

    @Override
    public Map<String,Object> detail(Long id) {
        Map<String,Object> result = new HashMap<>();
        result.put("data",super.getById(id));
        result.put("optRecord",conOperateService.listByConId(id));
        result.put("contractLabels",conAllLabelService.listByConId(id));
//        result.put("files",conFilesService.listByConId(id));
        List<ConFiles> conFiles = conFilesService.listByConId(id);
        if(conFiles!=null && conFiles.size()>0){
            conFiles.stream().forEach(c->{
                c.setUrl(c.getUrl().replace(httpUrl, httpsUrl));
                c.setNewUrl(c.getUrl());
            });
        }
        result.put("files",conFiles);
        return result;
    }
    @Resource
    BpmInstanceService bpmInstanceService;
    @Override
    public void excellent(ConExcellentCases conExcellentCases, String currentUserName) {
        ConThirdPartyMeasurement conThirdPartyMeasurement = super.getById(conExcellentCases.getId());
        if(conThirdPartyMeasurement == null){
            throw new BusException("申请失败!,该合同不存在",BaseResultCode.GENERAL_ERROR);
        }
        ConExcellentCases existByConId = conExcellentCasesService.getAllByConId(conExcellentCases.getId());
        if(existByConId != null){
            throw new BusException("该合同已经存在优秀案例",BaseResultCode.GENERAL_ERROR);
        }
        conExcellentCases.setId(null);
        conExcellentCases.setContractName(conThirdPartyMeasurement.getContractName());
        conExcellentCases.setContractNumber(conThirdPartyMeasurement.getContractNumber());
        conExcellentCases.setConId(conThirdPartyMeasurement.getId());
        conExcellentCases.setTypeOfContract(4);
        conExcellentCases.setApplicant(currentUserName);
        conExcellentCases.setCreateBy(SecurityUtils.getUsername());

        //启动审批流程
        ProcessInstanceParam param = new ProcessInstanceParam();
        param.setBussinessId(conThirdPartyMeasurement.getId());
        param.setBpmKey(BpmInstanceService.CON_RESOURCE_BOM_KEY);
        Map<String,Object> map = new HashMap<>();
        try {
            map = ObjectUtils.objectToMap(conExcellentCases);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        map.put("serviceType",4);
        map.put("moduleName","第三方计量合同");
        map.put("reason",conExcellentCases.getExcellent());
        param.setParams(map);
        String processInstanceId = bpmInstanceService.startProcessInstance(param);
        conExcellentCases.setProcessInstanceId(processInstanceId);
        //conExcellentCases.setCreateBy(SecurityUtils.getUsername());
        conExcellentCasesService.save(conExcellentCases);
        conThirdPartyMeasurement.setExcellent(1);
        super.updateById(conThirdPartyMeasurement);
    }

    @Override
    public void saveCon(ConThirdPartyMeasurement conThirdPartyMeasurement) {
        // 设置合同状态默认值为 已签订
        if(StringUtils.isNotBlank(conThirdPartyMeasurement.getFilePath())){
            conThirdPartyMeasurement.setStatus(2);
        }else{
            conThirdPartyMeasurement.setStatus(1);
        }

        conThirdPartyMeasurement.setContractName(editContractName(conThirdPartyMeasurement));
        conThirdPartyMeasurement.setContractNumber(editContractNumbers(conThirdPartyMeasurement));
        if (conThirdPartyMeasurement.getComeIntoForceDate() != null && conThirdPartyMeasurement.getContractValidity().intValue() != 0){
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = formatter.format(conThirdPartyMeasurement.getComeIntoForceDate());
            LocalDate localDate = LocalDate.parse(formattedDate);
            LocalDate nextYearDate = localDate.plus(conThirdPartyMeasurement.getContractValidity().intValue(), ChronoUnit.YEARS);
            System.out.println(nextYearDate);
            Date time = Date.from(nextYearDate.atTime(LocalTime.MIDNIGHT).atZone(ZoneId.systemDefault()).toInstant());
            conThirdPartyMeasurement.setExpirationDate(time);
        }
        //计算到期时间
//        Date str1 = conThirdPartyMeasurement.getSigningDate();
//
//        BigDecimal str2 = conThirdPartyMeasurement.getContractValidity();
//        int validYears = str2.intValue();
//        LocalDate signingDate = str1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
//        Period period = Period.ofYears(validYears);
//        LocalDate finalDate = signingDate.plus(period);
//        Date str3 = Date.from(finalDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
//
//        conThirdPartyMeasurement.setExpirationDate(str3);

        super.save(conThirdPartyMeasurement);
        if (StringUtils.isNotEmpty(conThirdPartyMeasurement.getFilePath())){
            ConFiles conFile = new ConFiles();
            conFile.setConId(conThirdPartyMeasurement.getId());
            conFile.setFileType(1);
            String path = conThirdPartyMeasurement.getFilePath();
            conFile.setUrl(path);
            conFile.setNewUrl(path);
            conFile.setFileName(path.substring(path.lastIndexOf("/")+1,path.length()));
            conFile.setScanPdf(FileUtil.getIsScanPdf(path));
            //保存附件
            conFilesService.save(conFile);
        }

        conOperateService.saveByCon("新增合同",conThirdPartyMeasurement.getId());
    }

    @Override
    public void updateCon(ConThirdPartyMeasurement conThirdPartyMeasurement) {
        //获取原信息
        ConShipping OldConResourceMain = conThirdPartyMeasurementMapper.getById(conThirdPartyMeasurement.getId());
        //原合同编号尾号+1，方便比较
        String oldContractNumber = incrementLastDigit(OldConResourceMain.getContractNumber());
        conThirdPartyMeasurement.setContractName(editContractName(conThirdPartyMeasurement));
        if (conThirdPartyMeasurement.getComeIntoForceDate() != null && conThirdPartyMeasurement.getContractValidity().intValue() != 0){
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = formatter.format(conThirdPartyMeasurement.getComeIntoForceDate());
            LocalDate localDate = LocalDate.parse(formattedDate);
            LocalDate nextYearDate = localDate.plus(conThirdPartyMeasurement.getContractValidity().intValue(), ChronoUnit.YEARS);
            System.out.println(nextYearDate);
            Date time = Date.from(nextYearDate.atTime(LocalTime.MIDNIGHT).atZone(ZoneId.systemDefault()).toInstant());
            conThirdPartyMeasurement.setExpirationDate(time);
        }
        String newContractNumbers = editContractNumbers(conThirdPartyMeasurement);
        if (newContractNumbers.equals(oldContractNumber)){
            conThirdPartyMeasurement.setContractNumber(OldConResourceMain.getContractNumber());
        }else {
            conThirdPartyMeasurement.setContractNumber(newContractNumbers);
        }
        super.updateById(conThirdPartyMeasurement);

        ConExcellentCases conExcellentCases = conExcellentCasesService.getAllByConId(conThirdPartyMeasurement.getId());
        if(conExcellentCases != null){
            conExcellentCases.setContractName(conThirdPartyMeasurement.getContractName());
            conExcellentCases.setContractNumber(conThirdPartyMeasurement.getContractNumber());
            conExcellentCasesService.updateById(conExcellentCases);
        }

        conOperateService.saveByCon("修改合同",conThirdPartyMeasurement.getId());
    }
    //根据信息拼接合同名字
    @Override
    public String editContractName(ConThirdPartyMeasurement conThirdPartyMeasurement){
        String str1 = constantMapper.findConstLabel("贸易主体", String.valueOf(conThirdPartyMeasurement.getTradeBody()));
        String str2 = conThirdPartyMeasurement.getPartyB();
        Date signingDate = conThirdPartyMeasurement.getSigningDate();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
        String str3 = sdf.format(signingDate);
        String ContractName = "MSC-"+str1+"-"+str2+"-"+str3;
        return ContractName;
    }

    //根据信息拼接合同编号
    @Override
    public String editContractNumbers(ConThirdPartyMeasurement conThirdPartyMeasurement){
        // 获取所有合同编号
        List<String> strings = conThirdPartyMeasurementMapper.getAllContractNumbers();
        // 创建合同编号对象
        String ContractNum;
        // 合同编号拼接
        int maxNumber = extractAndFindMaxNumber(strings, "MSC");
        ContractNum = "MSC-"+maxNumber;
        return ContractNum;
    }

    @Override
    public void contractExpireMessageSend() {
        List<ConThirdPartyMeasurement> contractList = this.baseMapper.selectList(
                new LambdaQueryWrapper<ConThirdPartyMeasurement>()
                        .ge(ConThirdPartyMeasurement::getExpirationDate,new Date())
        );
        if(contractList.size() == 0){
            return;
        }
        List<SysMessageSend> messageSendList = new LinkedList<>();
        for (ConThirdPartyMeasurement contractInfo : contractList) {
            SysMessageSend messageSend = new SysMessageSend();
            messageSend.setMessageUrl(ModuleUrlEnum.DSFJLHTXQ.getUrl()+contractInfo.getId());
            messageSend.setMessageType(MessageTypeEnum.MESSAGE_TYPE_4.getCode());
            messageSend.setContentParam(new String[]{contractInfo.getContractName()
                    ,contractInfo.getContractNumber()
                    , DateUtils.parseDateToStr("yyyy-MM-dd",contractInfo.getExpirationDate())});
            messageSend.setCompareType(5);
            messageSend.setCompareValue(DateUtil.getDateDays(new Date(),contractInfo.getExpirationDate(),1).intValue());
            List<String> otherUid = new LinkedList<>();
            otherUid.add(contractInfo.getCreateBy());
            messageSend.setOtherUsernameList(otherUid);
            messageSendList.add(messageSend);
        }
        remoteMessageSendService.messageSendBatch(messageSendList);
    }
}
